﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Linq.Expressions;

namespace NeGroid.ChampionshipManager.Persistance
{
	public class EfRepository<TEntity> : IRepository<TEntity>
		where TEntity : class
	{
		protected readonly ChampionshipManagerDb DbContext;
		protected readonly DbSet<TEntity> Entities;

		public EfRepository(ChampionshipManagerDb dbContext)
		{
			DbContext = dbContext;
			Entities = dbContext.Set<TEntity>();
		}
		public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
			SortOptions sortOptions = null,
			string includeProperties = "")
		{
			IQueryable<TEntity> query = Entities;

			if (filter != null)
			{
				query = query.Where(filter);
			}

			query = includeProperties
				.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));

			if (sortOptions != null)
				query = query.OrderBy(sortOptions);

			return query.ToList();
		}

		public virtual void Insert(TEntity entity)
		{
			Contract.Requires(entity != null);
			Contract.Ensures(Entities.Contains(entity));

			Entities.Add(entity);
		}

		public virtual void Delete(TEntity entity)
		{
			Contract.Requires(entity != null);
			Contract.Requires(Entities.Contains(entity));
			Contract.Ensures(!Entities.Contains(entity));

			Entities.Remove(entity);
		}

		public virtual void Update(TEntity entity)
		{
			Contract.Requires(entity != null);
			Contract.Requires(Entities.Contains(entity));

			DbContext.Entry(entity).State = EntityState.Modified;
		}

		public virtual void SaveChanges()
		{
			DbContext.SaveChanges();
		}
	}
}
